package cn.zurish.cloud.security.handler.impl1;

import cn.zurish.cloud.security.dao.entity.SysPolicy;
import cn.zurish.cloud.security.dao.entity.SysUser;
import cn.zurish.cloud.security.dao.mapper.SysPolicyMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
public class AbacDecisionEngine {
    private final SpelExpressionParser parser = new SpelExpressionParser();

    @Autowired
    private SysPolicyMapper sysPolicyMapper;

    public boolean check(Authentication authentication, String resource) {
        SysUser userDetails = (SysUser) authentication.getPrincipal();

        // 加载策略集
        LambdaQueryWrapper<SysPolicy> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysPolicy::getTargetResource, resource);
        List<SysPolicy> policies = sysPolicyMapper.selectList(queryWrapper);
        if (policies.isEmpty()) {
            return false;
        }

        // 构建评估上下文
        EvaluationContext context = new StandardEvaluationContext();
        // 将用户传入表达式上下文 如：#user.attrs['department'] == 'IT'
        // 其中user前缀就是我们传入的user
        context.setVariable("user", userDetails);
        return policies.stream().allMatch(policy ->
                parser.parseExpression(policy.getConditionExpression()).getValue(context, Boolean.class)
        );
    }
}
